package com.guigu.tomcat.impl;

import com.guigu.tomcat.*;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class TomcatImpl implements Tomcat {
    private String webroot = "F:\\Test\\老王的个人博客(6.5)";


    //单列集合 list可重复 set不可重复
    //双列集合 map
    //servlet 容器
    private Map<String, HttpServlet> servletMap = new HashMap<>();

    {//块分为静态块和实例块 块是没有名字的构造函数 块在构造函数之前执行
        servletMap.put("/hello.do", new HelloServlet());
        servletMap.put("/get.do", new LoginServlet());
        servletMap.put("/cookie.do", new CookieServlet());
        servletMap.put("/session.do", new SessionServlet());
        servletMap.put("/redirect.do", new RedirectServlet());

    }

    public static void main(String[] args) {
        new TomcatImpl().start(8080);
    }

    @Override
    public void start(int port) {
        ServerSocket server = null;
        System.out.println("启动服务器：" + port);
        try {
            server = new ServerSocket(port);
            while (true) {
                Socket socket = server.accept();
                //构建请求和响应对象
                HttpServletRequest httpServletRequest = buildRequest(socket);
                HttpServletResponse httpServletResponse = buildResponse(socket, httpServletRequest);
                System.out.println(httpServletRequest);

                if (isServletRequest(httpServletRequest)) {

                    //servlet
                    String uri = getURI(httpServletRequest);
                    HttpServlet servlet = servletMap.get(uri);
                    try {
                        //service 分发请求
                        servlet.service(httpServletRequest, httpServletResponse);

                        //获取会话对象
                        HttpSession session = httpServletRequest.getSession();
                        //获取会话id
                        String id = session.getId();
                        //写入cookie
                        Cookie cookie = new CookieImpl("JSESSIONID", id);
                        //不能设置有效期
                        httpServletResponse.addCookie(cookie);
                        //数据推送到服务器
                        httpServletResponse.flushBuffer();

                    } catch (ServletException e) {
                        throw new RuntimeException(e);
                    }
                } else if (isStaticRequest(httpServletRequest)) {
                    //处理静态请求
                    processStaticRequest(httpServletRequest, httpServletResponse);
                } else {
                    //404错误
                    //返回404页面
                    PrintWriter writer = httpServletResponse.getWriter();
                    httpServletResponse.setContentType("text/html;charset=utf-8");
                    writer.append("<h2>404</h2><h3>访问资源丢失</h3>");
                    httpServletResponse.setStatus(404, "Not Foud");
                    httpServletResponse.flushBuffer();

                }

                socket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private String getURI(HttpServletRequest httpServletRequest) {
        String uri = httpServletRequest.getRequestURI();
        if (uri.indexOf("?") > 0) {
            uri = uri.substring(0, uri.indexOf("?"));
        }
        return uri;

    }

    @Override
    public boolean isStaticRequest(HttpServletRequest request) {
        String filepath = webroot + request.getRequestURI();
        // System.out.println(filepath);
        //截取？前面的路径
        if (filepath.indexOf("?") > 0) {
            filepath = filepath.substring(0, filepath.indexOf("?"));
        }
//物理文件存在那么是静态请求
        return new File(filepath).exists();
    }

    @Override
    public boolean isServletRequest(HttpServletRequest request) {
        String uri = getURI(request);
        return servletMap.containsKey(uri);
    }

    @Override
    public HttpServletRequest buildRequest(Socket socket) {
        try {

            return new HttpServletRequestImpl(socket);
        } catch (IOException e) {
            //异常转型==》异常链 IO异常属于编译时异常
            throw new RuntimeException(e);

        }

    }

    @Override
    public HttpServletResponse buildResponse(Socket socket, HttpServletRequest request) {
        try {
            return new HttpServletResponseImpl(socket);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }


    @Override
    public boolean processStaticRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //响应输出流
        OutputStream out = response.getOutputStream();

        out.write("HTTP/1.1 200 OK\n".getBytes());
        String contentType = getMimeType(request.getRequestURI());
        out.write(("Content-Type:" + contentType + "\n").getBytes());
        out.write("\n".getBytes());


        String filepath = webroot + request.getRequestURI();
        System.out.println(request.getRequestURI());
        System.out.println(filepath);
        //截取？前面的路径
        if (filepath.indexOf("?") > 0) {
            filepath = filepath.substring(0, filepath.indexOf("?"));
        }
        try (FileInputStream fis = new FileInputStream(filepath)) {
            byte[] bytes = new byte[1024];
            int count;
            while ((count = fis.read(bytes)) > 0) {
                out.write(bytes, 0, count);
            }
        }
        return true;
    }

    @Override
    public boolean processServletRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        return false;
    }

    Map<String, String> mimeMap = new HashMap<>();

    {
        try {
            SAXReader reader = new SAXReader();
            Document doc = reader.read(new File("D:\\Program Files\\apache-tomcat-9.0.65\\conf/web.xml"));
            //获取根节点
            Element root = doc.getRootElement();
            //获取元素迭代器
            Iterator<Element> elementIterator = root.elementIterator("mime-mapping");
            while (elementIterator.hasNext()) {
                //获取下一个元素
                Element element = elementIterator.next();
                Element extension = element.element("extension");
                Element mimeType = element.element("mime-type");
                String ext = extension.getText();
                String mimeTypeText = mimeType.getText();
                
                mimeMap.put(ext, mimeTypeText);
            }
        } catch (DocumentException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public String getMimeType(String path) {
      /*  if (path.endsWith(".css")) {
            return "text/css";
        } else if (path.endsWith(".js")) {
            return "application/X-javascript";

        } else {
            return "text/html;charset=utf-8";
        }*/
        String ext = path.replaceAll(".+\\.(\\w+)","$1");
        String mimeType = mimeMap.get(ext);
        System.out.println(mimeType);
        return mimeType;
    }

    @Override
    public HttpServlet getServlet(HttpServletRequest request) {
        return null;
    }

    @Override
    public void createSession(HttpServletRequest request, HttpServletResponse response) {

    }

    @Override
    public void stop() {

    }
}
